<template>
  <view class="tui-lottie__box">
    <!-- #ifdef MP -->
    <canvas id="lottie_canvas" :style="{width:mpW+'px',height:mpH+'px'}" canvas-id="lottie_canvas"
            class="lottie_canvas" type="2d"></canvas>
    <!-- #endif -->

    <!-- #ifdef APP-VUE || H5 -->
    <view id="lottieRef" ref="lottieRef" :action="actionVal" :change:action="animation.changeAction"
          :change:prop="animation.changeProp"
          :prop="options" :style="{width:width+'rpx',height:height+'rpx'}"></view>
    <!-- #endif -->
  </view>
</template>

<!-- #ifdef APP-VUE || H5 -->
<script lang="renderjs" module="animation">
import lottie from './lottie.render.js'

export default {
  data() {
    return {
      ani: null,
      action_old: '',
      isInit: false
    }
  },
  methods: {
    changeProp(vals, old) {
      let isVue3App = false
      // #ifdef APP-VUE
      // #ifdef VUE3
      isVue3App = true;
      // #endif
      // #endif
      if (!this.isInit && !isVue3App) return;
      this.init(vals || old)
    },
    changeAction(newVal, oldVal) {
      const action = newVal || oldVal
      if (action === this.action_old) return;
      this.action_old = action;
      try {
        this.ani && this.ani[action]()
      } catch (e) {
        //TODO handle the exception
      }
    },
    init(vals) {
      if (!vals || (!vals.path && !vals.animationData)) return;
      this.ani && this.ani.destroy();
      this.$nextTick(() => {
        this.ani = lottie.loadAnimation({
          // #ifndef H5
          container: document.getElementById('lottieRef'),
          // #endif
          // #ifdef H5
          container: this.$refs.lottieRef.$el,
          // #endif
          renderer: 'svg',
          loop: vals.loop === undefined ? true : vals.loop,
          autoplay: vals.autoplay === undefined ? true : vals.autoplay,
          path: vals.path,
          // 只能加载本地json，优先级高于path
          animationData: vals.animationData
        });
      })
    }
  },
  mounted() {
    this.init(this.options)
    setTimeout(() => {
      this.isInit = true;
    }, 200)
  }
}
</script>
<!-- #endif -->

<script>
// #ifdef MP
import lottieMp from './lottie.mp.js'
// #endif
export default {
  name: "tui-lottie",
  props: {
    width: {
      type: [Number, String],
      default: 600
    },
    height: {
      type: [Number, String],
      default: 400
    },
    options: {
      type: Object,
      default() {
        return {
          path: '',
          animationData: '',
          autoplay: true,
          loop: true
        }
      }
    },
    //动画操作，可取值 play、pause、stop、destroy
    action: {
      type: String,
      default: 'play'
    }
  },
  watch: {
    // #ifdef MP
    actionVal() {
      this.changeMpAction()
    },
    options() {
      if (!this.mpInitFlag) return;
      this.initMp();
    },
    // #endif
    action(val) {
      this.actionVal = this.getAction(this.action)
    }
  },
  data() {
    return {
      // #ifdef MP
      mpW: 300,
      mpH: 200,
      // #endif
      //可取值 play、pause、stop、destroy
      actionVal: ''
    };
  },
  // #ifdef VUE2
  beforeDestroy() {
    this.actionVal = 'destroy'
  },
  // #endif
  // #ifdef VUE3
  beforeUnmount() {
    this.actionVal = 'destroy'
  },
  // #endif
  // #ifdef MP
  created() {
    this.aniMp = null
    this.mpInitFlag = false
    this.mpW = uni.upx2px(Number(this.width))
    this.mpH = uni.upx2px(Number(this.height))
  },
  // #endif
  mounted() {
    this.actionVal = this.getAction(this.action)
    // #ifdef MP
    this.initMp()
    // #endif
  },
  methods: {
    // #ifdef MP
    changeMpAction() {
      try {
        this.aniMp && this.aniMp[this.actionVal]()
      } catch (e) {
        //TODO handle the exception
      }
    },
    initMp() {
      const options = {
        ...this.options
      }
      if (!options.path && !options.animationData) return;
      this.aniMp && this.aniMp.destroy();
      this.$nextTick(() => {
        const query = uni.createSelectorQuery()
            // #ifndef MP-ALIPAY
            .in(this)
        // #endif
        query.selectAll('.lottie_canvas').node(res => {
          const canvas = res[0].node;
          const context = canvas.getContext('2d');
          const dpr = uni.getSystemInfoSync().pixelRatio;
          canvas.width = this.mpW * dpr;
          canvas.height = this.mpH * dpr;
          context.scale(dpr, dpr);
          lottieMp.setup(canvas)

          this.aniMp = lottieMp.loadAnimation({
            loop: options.loop === undefined ? true : options.loop,
            autoplay: options.autoplay === undefined ? true : options.autoplay,
            //只支持网络地址
            path: options.path,
            animationData: options.animationData,
            rendererSettings: {
              context,
            },
          })
          this.mpInitFlag = true
        }).exec()
      });
    },
    // #endif
    getAction(action) {
      const actions = ['play', 'pause', 'stop', 'destroy']
      let val = 'play'
      if (~actions.indexOf(action)) {
        val = action
      }
      return val
    }
  }
}
</script>

<style scoped>
.tui-lottie__box {
  display: inline-flex;
}
</style>
